import java.util.Scanner;

/**
 * Description:
 * Date: 2025-10-23
 * Time: 13:21
 */


public class Test {

    //异常：在java程序运行时出现的错误。一般指程序运行过程中发生的、中断正常执行流程的事件
    //异常分为：编译时异常/受查异常 和 运行时异常/非受查异常

    public static void main1(String[] args) {
        //算术异常 ArithmeticException 是运行时异常，只有在程序运行时才会抛出错误
        int a = 10 / 0;
        System.out.println(a);
    }

    public static void main2(String[] args) {
        //数据越界异常:ArrayIndexOutOfBoundsException （运行时异常）
        int[] array = new int[10];
        int a = array[10];
        System.out.println(a);
    }

    public static void main3(String[] args) {
        //空指针异常：NullPointerException (运行时异常)
        int[] array = new int[10];
        array = null;
        int lent = array.length;//一个空的引用去访问某个方法或某个变量
        System.out.println(lent);
    }

    public static void func1() {
        //throw 关键字：能够抛出一个异常，当程序执行到这步时，如果没有对抛出的异常进行处理，则程序会强制结束。后面的代码也不会执行
        throw new ArithmeticException();
    }

    //throws 关键字：用来声明一个受查异常，使该方法能正常通过编译
    //当一个方法内出现了编译时异常，暂时不想处理时，就使用throws关键字抛给这个方法的调用者(往上抛)来进行处理
    // 循环往返，直至异常被处理或者抛到main方法中，当main方法也没有处理时，就会交给JVM进行处理，最终是异常被处理或者程序中断

    //当方法内有多个异常时，throws可以抛出多个异常来解决编译时异常，保障程序能正常编译(但不能保障程序能正常运行)
    public static void main4 (String[] args) throws ArithmeticException,NullPointerException{
        func1();
    }



    public static void main5(String[] args) {
        //try - catch 关键字,用来处理异常，使程序继续运行下去
        int[] arr = new int[3];
        //try中放置可能会含有异常的语句
        try {
            arr = null;
            System.out.println(arr.length);
            //try中发生异常的语句，在try中它之后的语句不会执行
            System.out.println("程序执行。。。。");
        //catch关键字捕获异常
        //若try抛出的异常类型与catch捕获的类型一致时，就会被catch捕获
        }catch (NullPointerException e){
            e.printStackTrace();
            System.out.println("异常被捕获了！");
        }
        System.out.println("程序运行到这里！");
    }

    public static void main6(String[] args) {
        //try-catch可以捕获多个异常
        int[] arr = new int[3];
        try {
            //先发生算术异常，则程序直接跳到catch代码块中。
            //后面的数组越界异常不会发生，因为不执行
            int ret = arr[2] / 0;
            arr[5] = 0;
        //设置了多个catch来捕获多个异常类型，识别到哪个异常，就跳到捕获哪个异常的catch中执行
        }catch (ArrayIndexOutOfBoundsException e){
            e.printStackTrace();
        }catch (ArithmeticException e){
            e.printStackTrace();
        }
        System.out.println("异常处理，程序执行！");
    }

    public static void main7(String[] args) {
        //try-catch-fianlly关键字
        int[] arr = new int[3];
        try {
            int ret = arr[5];
        }catch (ArithmeticException e) {
            e.printStackTrace();
        }finally {
            //就算发生了异常，并且异常没有被处理或者捕获，程序不执行了
            //finally中的代码也一定会执行
            System.out.println("finally中的程序一定会执行了");
        }

        System.out.println("main方法中的程序执行了");
    }

    public static int func2() {
        Scanner scanner = new Scanner(System.in);

        try {
            int a = scanner.nextInt();
            int b = a / 1;
            return b;
        }catch (ArithmeticException e) {
            e.printStackTrace();
        }finally {
            //因为fianlly中的代码一定会执行，所以一般用来回收程序中的资源
            scanner.close();
            System.out.println("finally被执行了！");
            //若是在finally中有return语句
            //则：finally返回的值会覆盖掉其余return语句中的值，只会保留fianlly语句中的retuan值
            //一旦finally中写了return，则会立即产生返回指令，后面就无法写代码，返回流已经产生，后面代码执行不了
            return 22;
        }

    }

    public static void main9(String[] args) {
        //finally：因其一定会执行的特性，finally一般用来进行资源的回收
        System.out.println(func2());
    }

    public static void main10(String[] args) {
        int[] arr = new int[3];
        try {
            arr[5] = 10;
            int a = 21 / 0;
        }catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
            //Exception是所有异常类的父类，可以捕获任何异常类型
            //注：父类异常需排在子类异常后，父类异常在前，就没有必要再写子类异常了
            //  故子类异常在前是为了单独捕获该异常，父类异常在后是兜底
        }catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("程序执行了！");
    }

    public static void login() throws NameException{
        Person person = new Person("zxc","z123");
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();

        if(!(name.equals(person.nameUser))){
            //通过异常的方式来表示输入的账号错误
            //此时时编译时异常，需要throws来抛出异常给调用者，使程序能通过编译来正常执行
            throw new NameException("账号错误！");
            /*System.out.println("账号错误！");
            return;*/
        }
        String passWord = scanner.nextLine();
        if (!(passWord.equals(person.passWord))) {
            //可以在括号中用双引号输入异常出现的原因
            throw new passWordException("密码错误！");
            /*System.out.println("密码错误！");
            return;*/
        }
        System.out.println("登录成功！");
    }

    //throws声明的异常一般是编译时异常。
    //第一个作用是让通过编译器的编译，使程序能正常执行
    //第二个作用是将方法网上抛，直到异常被处理或者交给JVM处理(这是一般会编译报错)
    //   当然，throws只是声明有可能会发生异常错误
    //   若程序执行过程中没有异常出现，则它的作用就是当前方法中的编译时异常通过编译器的检查，使程序能过执行起来
    public static void main(String[] args) throws NameException{
        //自定义异常类:
        login();

        /*try {
            login();
        }catch (NameException e) {
        //e代表被捕获的异常对象
            e.printStackTrace();
        }catch (AgeException e) {
            e.printStackTrace();
        }*/
    }

}
